﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.Remoting.Messaging;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace _15_异步委托
{
    public delegate int AddDelegate(int a, int b,out string resultStr);

    internal class Program
    {
        public static int Add(int a, int b, out string reusltStr)
        {
            Thread.Sleep(5000);//模拟耗时操作(计算过程)，休眠5秒
            int result = a + b;
            reusltStr = string.Format("{0}+{1}={2}", a, b, result);
            return result;
        }

        static void Main(string[] args)
        {
            //创建委托对象
            AddDelegate addDelegate = new AddDelegate(Add);

            //提示开始调用委托
            Console.WriteLine("[{0}] 开始调用委托",DateTime.Now);

            //同步委托
            //int value = addDelegate.Invoke(10, 20, out string resultStr);

            //调用异步委托
            //参数一：委托的第一个参数
            //参数二：委托的第二个参数
            //参数三：out 委托的输出参数
            //参数四：委托的回调函数，当异步委托执行完毕后，会调用回调函数
            //参数五：传递给回调函数的参数，可以为null
            //返回值：IAsyncResult接口，用于获取异步委托的返回值
            IAsyncResult asyncResult = addDelegate.BeginInvoke(12, 30, out string resultStr, null, null);

            //模拟执行其他操作
            Console.WriteLine("[{0}] 执行其他操作", DateTime.Now);

            for (int i = 0; i < 3; i++)
            {
                Console.WriteLine("[{0}] 执行其他操作-{1}", DateTime.Now, i);
                Thread.Sleep(1000);
            }

            Console.WriteLine("[{0}] 主线程执行完毕！",DateTime.Now);

            //获取异步委托的返回值，如果委托没有执行完毕，会阻塞当前线程
            int value = addDelegate.EndInvoke(out resultStr, asyncResult);

            //获取委托的返回值，打印输出
            Console.WriteLine("[{0}] 表达式:{1}", DateTime.Now, resultStr);
            Console.WriteLine("[{0}] 委托返回值：{1}", DateTime.Now, value);

            Console.Read();



        }

        //public static void AddCompleted(IAsyncResult asyncResult)
        //{
        //    //获取委托对象
        //    AddDelegate addDelegate = (AddDelegate)((AsyncResult)asyncResult).AsyncDelegate;
        //    //获取委托的返回值
        //    int value = addDelegate.EndInvoke(out string resultStr, asyncResult);//阻塞当前线程，直到委托执行完毕
        //    //获取委托的返回值，打印输出
        //    Console.WriteLine("[{0}] 表达式:{1}", DateTime.Now, resultStr);
        //    Console.WriteLine("[{0}] 委托返回值：{1}", DateTime.Now, value);
        //}

    }
}
